package com.pozzo.tpcintegration;


import java.text.SimpleDateFormat;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.FixedSubscriberChannel;
import org.springframework.integration.ip.tcp.TcpInboundGateway;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.TcpSendingMessageHandler;
import org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNioClientConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;
/**
 * @Author: kaiyuan.zheng
 * @Date: 1:39 2021/10/11
 * @Description:
 */
@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Autowired
    private Gateway gateway;

    @Scheduled(fixedDelay = 1000L)
    public void sendMessageJob() {
        String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis());
        String msg = "{\"currentTime\":\"" + currentTime + "\"}";
        System.out.println("客户端发送消息" + msg);
        gateway.sendMessage(msg);
    }

    // server
    @Bean
    public AbstractServerConnectionFactory serverConnectionFactory() {
        return new TcpNioServerConnectionFactory(5678);
    }

    @Bean
    public MessageChannel requestChannel() {
        return new DirectChannel();
    }

    @Bean
    public TcpInboundGateway tcpInboundGateway() {
        TcpInboundGateway tcpInboundGateway = new TcpInboundGateway();
        tcpInboundGateway.setConnectionFactory(serverConnectionFactory());
        tcpInboundGateway.setRequestChannel(requestChannel());
        return tcpInboundGateway;
    }

    @Transformer(inputChannel = "requestChannel", outputChannel = "requestChannel2")
    public String serverConvert(byte[] bytes) {
        return new String(bytes);
    }

    @ServiceActivator(inputChannel = "requestChannel2")
    public String handleRequest(String msg) throws Exception {
        System.out.println("服务端处理请求消息=" + msg);// server handle
        ObjectMapper objectMapper = new ObjectMapper();
        Map map = objectMapper.readValue(msg, Map.class);
        map.put("result", "is processed");
        return objectMapper.writeValueAsString(map);
    }

    // client
    @Bean
    public AbstractClientConnectionFactory clientConnectionFactory() {
        return new TcpNioClientConnectionFactory("localhost", 5678);
    }

    @Component
    @MessagingGateway(defaultRequestChannel = "sendMessageChannel")
    public interface Gateway {
        void sendMessage(String message);
    }

    @Bean
    @ServiceActivator(inputChannel = "sendMessageChannel")
    public TcpSendingMessageHandler tcpSendingMessageHandler() {
        TcpSendingMessageHandler tcpSendingMessageHandler = new TcpSendingMessageHandler();
        tcpSendingMessageHandler.setConnectionFactory(clientConnectionFactory());
        return tcpSendingMessageHandler;
    }

    @Bean
    public TcpReceivingChannelAdapter tcpReceivingChannelAdapter() {
        TcpReceivingChannelAdapter tcpReceivingChannelAdapter = new TcpReceivingChannelAdapter();
        tcpReceivingChannelAdapter.setConnectionFactory(clientConnectionFactory());
        tcpReceivingChannelAdapter.setOutputChannelName("outputChannel");
        return tcpReceivingChannelAdapter;
    }

    @Transformer(inputChannel = "outputChannel", outputChannel = "outputChannel2")
    public String clientConvert(byte[] bytes) {
        return new String(bytes);
    }

	/*@Bean
	public MessageChannel outputChannel2() {
		return new FixedSubscriberChannel(msg -> {
			System.out.println("客户端处理响应消息=" + msg.getPayload());// client handle
		});
	}

	@Bean
	@ServiceActivator(inputChannel = "outputChannel2")
	public MessageHandler handleResponse() {
		return msg -> {
			System.out.println("客户端处理响应消息=" + msg.getPayload());// client handle
		};
	}*/

    @ServiceActivator(inputChannel = "outputChannel2")
    public String handleResponse(String msg) throws Exception {
        System.out.println("客户端处理响应消息=" + msg);// client handle
        return null;
    }

}

